﻿using Hangfire.Client;
using Hangfire.Common;
using Hangfire.Logging;
using Hangfire.Server;
using Hangfire.States;
using Hangfire.Storage;

namespace Hangfire_Demo.HFCustom
{
    /// <summary>
    /// 过程日志输出
    /// https://www.cnblogs.com/fanfan-90/p/16303553.html
    /// </summary>
    public class LogEverythingAttribute : JobFilterAttribute,
    IClientFilter, IServerFilter, IElectStateFilter, IApplyStateFilter
    {
        private static readonly ILog Logger = LogProvider.GetCurrentClassLogger();

        /// <summary>
        /// IClientFilter
        /// </summary>
        /// <param name="context"></param>
        public void OnCreating(CreatingContext context)
        {
            Logger.InfoFormat("Creating a job based on method `{0}`...", context.Job.Method.Name);
        }

        /// <summary>
        /// IClientFilter
        /// </summary>
        /// <param name="context"></param>
        public void OnCreated(CreatedContext context)
        {
            Logger.InfoFormat(
                "Job that is based on method `{0}` has been created with id `{1}`",
                context.Job.Method.Name,
                context.BackgroundJob?.Id);
        }
        /// <summary>
        /// IServerFilter
        /// </summary>
        /// <param name="context"></param>
        public void OnPerforming(PerformingContext context)
        {
            Logger.InfoFormat("Starting to perform job `{0}`", context.BackgroundJob.Id);
        }
        /// <summary>
        /// IServerFilter
        /// </summary>
        /// <param name="context"></param>
        public void OnPerformed(PerformedContext context)
        {
            Logger.InfoFormat("Job `{0}` has been performed", context.BackgroundJob.Id);
        }
        /// <summary>
        /// IElectStateFilter
        /// </summary>
        /// <param name="context"></param>
        public void OnStateElection(ElectStateContext context)
        {
            var failedState = context.CandidateState as FailedState;
            if (failedState != null)
            {
                Logger.WarnFormat(
                    "Job `{0}` has been failed due to an exception `{1}`",
                    context.BackgroundJob.Id,
                    failedState.Exception);
            }
        }
        /// <summary>
        /// IApplyStateFilter
        /// </summary>
        /// <param name="context"></param>
        /// <param name="transaction"></param>
        public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
        {
            Logger.InfoFormat(
                "Job `{0}` state was changed from `{1}` to `{2}`",
                context.BackgroundJob.Id,
                context.OldStateName,
                context.NewState.Name);
        }
        /// <summary>
        /// IApplyStateFilter
        /// </summary>
        /// <param name="context"></param>
        /// <param name="transaction"></param>
        public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
        {
            Logger.InfoFormat(
                "Job `{0}` state `{1}` was unapplied.",
                context.BackgroundJob.Id,
                context.OldStateName);
        }
    }

    //// 用法
    ////1.可以在方法，类 应用过滤器：
    ///[LogEverything]
    ////public class EmailService
    ////{
    ////    [LogEverything]
    ////    public static void Send() { }
    ////}
    ///
    //////2.可以 全局注册 应用过滤器
    ////GlobalJobFilters.Filters.Add(new LogEverythingAttribute());
    ///
    ///

}
